import React from 'react'
import { findDOMNode } from 'react-dom'
import { Modal, info, Button, Tip, success, TweetInput, Link, ImgTxt, Gallery } from '../../ui-components'
import util from '../../util'
import style from './style.newsfeed'
import styleContent from '../app/style.content'
import cx from 'classnames'
import moment from 'moment'
moment.locale('zh-cn')
import KudoItem from './KudoItem';

const IMAGES_PATH = process.env.NODE_ENV === 'production'? './static/images': './static/src/images'
import { tip,IconButton} from 'sq-ui';

const TipIconButton = tip(IconButton);

export default 
class Feed extends React.Component {

  readyDeletedComment = {}
  readyDeletedFeed = {}
  feedUpLock = false
  willUnmount = false

  state = {
    render: false,
    menu: false,

    // 加载更多
    loading: false,
    complete: false,
    empty: false,
    deleteFeed: false,
    deleteFeedComment: false,
    toggleTweetInput: false,
  }

  // 页码, 从1开始
  pageNumber = 1
  // 每页加载数目
  pageSize = 5

  decodeContent(str, users, key) {
    str = util.emoji.dec(str)
    str = str.split(/(@[^@\s]+)/)

    return str.map((v, i) => {
      if (!v) return null
      const find = util.find(users, u => ~v.indexOf(u.fullName))
      if (~v.indexOf('@') && !util.isNull(find)) {
        return (
          <Link 
            target="_blank"
            key={i}
            label={v} 
            to={`#/okr/objective-targetAll?userId=${find.userId}`}
          />
        )
      }
      if (/^\s+$/.exec(v)) return (
        <span key={i}>
          { util.space(v.length) }
        </span>
      )

      // emoji部分
      let match1
      let match2
      if ((match1 = v.match(/[\uD800-\uDBFF]/))) {
        if ((match2 = v.match(/[\uDC00-\uDFFF]/))) {
          return (
            <span 
              className={style.emoji}
              key={i} 
              dangerouslySetInnerHTML={{__html: twemoji.parse(v, { folder: '72x72', base: `${IMAGES_PATH}/emoji/`})}}/>
          )
        }
      }

      return (
        <span key={i}>{ v }</span>
      )
    })
  }

  componentWillReceiveProps(props) {
    //if (this.props.scrollTop < props.scrollTop) {
    //  this.fetchContent(props)
    //}

    let comment
    if (!util.isNull((comment = props.newsFeed.commentData[props.feedId]))) {
      const { amount=0, comments=[] } = comment
      // 加载完毕
      if (comments.length  == amount) {
        this.setState({
          complete: true
        })
      } else {
        this.setState({
          complete: false
        })
      }

      // 没有评论
      if (amount == 0) {
        this.setState({
          empty: true
        })
      } else {
        this.setState({
          empty: false
        })
      }
    }
  }

  getPageNumber() {
    const  { comments=[] } = this.props.newsFeed.commentData[this.props.feedId] || {}
    return Math.ceil(comments.length/this.pageSize) + 1
  }

  componentDidMount() {
    this.el = findDOMNode(this)
    this.fetchContent()

    util.bus.on('newsfeed:scroll', this.fetchContent)
  }

  componentWillUnmount() {
    this.willUnmount = true
    util.bus.off('newsfeed:scroll', this.fetchContent)
  }

  fetchComments(props) {
    if(this.willUnmount) return
    props = props || this.props
    this.setState({
      loading: true
    })
    if(this.willUnmount) return
    this.props.fetchFeedComments(props.feedId, {
      pageSize: this.pageSize,
      pageNumber: this.getPageNumber()
    }, () => {
      this.pageNumber += 1
      if(this.willUnmount) return
      this.setState({
        loading: false
      })
    })
  }

  handleMenu(action) {
    this[`request${action}Feed`]()
  }

  requestDeleteFeed(feed) {
    this.readyDeletedFeed = feed
    this.setState({
      deleteFeed: true
    })
  }

  handleDeleteFeed() {
    info('删除中..', true)
    this.props.deleteFeed(this.props.feedId, () => {
      success('删除成功!')
    })
    this.setState({
      deleteFeed: false
    })
  }

  closeMenu = () => {
    this.toggleMenu()
    util.unbind(document, 'click', this.closeMenu)
  }

  openMenu() {
    util.bind(document, 'click', this.closeMenu)
    this.toggleMenu()
  }

  toggleMenu() {
    this.setState({
      menu: !this.state.menu
    })
  }

  requestDeleteComment(comment) {
    this.readyDeletedComment = comment
    this.setState({
      deleteFeedComment: true
    })
  }

  handleDeleteComment() {
    this.props.deleteComment(this.props.feedId, this.readyDeletedComment.commentId, this.pageSize, () => {
      const { comments: prevComments, amount: prevAmount } = this.props.newsFeed.commentData[this.props.feedId] || {}
      if (prevComments.length < prevAmount) {
        this.props.refreshFeedComments(this.props.feedId, {
          pageSize: this.pageSize,
          pageNumber: 1
        })
      }
      success('删除评论成功!')
    })
    this.setState({
      deleteFeedComment: false
    })
  }

	handleReply(comment) {
		this.refs.input.focus()
		this.refs.input.setAt(comment.commentUser)
	}

  handleSubmit({ content, selectMap }, clear, reset) {

    let matches = []
    const match = content.match(/@[^@\s\n]+/g)
    if (match) matches = match.map(match => match.slice(1))

    const atUsers = matches
      .filter(name => selectMap[name])
      .map(name => selectMap[name])
		const { profile } = this.props

    // encode emoji
    //content = content.replace(/([\uD800-\uDBFF][\uDC00-\uDFFF])/g, (match, whole) => whole.replace(match, encodeURIComponent(match)))

    this.props.addComment(this.props.feedId, {
      content,
      atUsers,
      commentUser: profile,
      orgId: this.props.orgId,
      pageSize: this.pageSize
    }, () => {

      const prevComments = (this.props.newsFeed.commentData[this.props.feedId] || {}).comments || []
      // 展示到整页数时，需要翻页
      if ( prevComments.length && prevComments.length % this.pageSize == 0) {
        this.setState({
          complete: false,
          empty: false
        })
      }

      reset()
      success('评论已发布!')
      this.refs.input.blur();
    })
  }

  handleFeedUp() {
    if (this.feedUpLock) return
    this.feedUpLock = true
    this.props.feedUp(this.props.feedId, this.props.isLikable, () => {
      this.feedUpLock = false
      this.props.fetchFeedUps(this.props.feedId)
    })
  }

  fetchContent = props => {
    if (!this.el) return
    if (this.el.getBoundingClientRect().top - 100 < document.documentElement.clientHeight) {
      if (!this.state.render) {
        props = props || this.props
        this.fetchComments(props)
        //this.props.fetchFeedUps(props.feedId)
        this.setState({
          render: true
        })
      }
    }
  }

  fetchFeedImage(index, image) {
    this.props.fetchFeedImage({ feedId: this.props.feedId, uuid: image.uuid, index, size: 'middle' })
  }

  renderMenu() {
    const feedUser = util.user(this.props.feedUser)
    if (!this.state.menu) return null
    return (
      <ul 
        style={{
          'animationDuration': '200ms'
        }}
        className={style['feed-menu']}>
        {
          ['Delete|删除'].map((v,i) => {
            const [ name, label ] = v.split('|')
            return (
              <li key={i}>
                <a onClick={() => this.handleMenu(name)}>{ label }</a>
              </li>
            )
          })
        }
      </ul>
    )
  }

  renderImages() {
    if (util.isNull(this.props.images)) return null
    const images = this.props.images.map(img => ({
      ...img,
      uuid: img.uuid,
      thumbnail: img.url
    }))
    return (
      <Gallery 
        width="100"
        onLoad={::this.fetchFeedImage}
        className={cx(style.gallery)}
        images={images}/>
    )
  }
  renderKudo = () => {
    if(util.isNull(this.props.rewardVO)) return null;
    const {
      rewardVO = {}
    } = this.props;
    const {
      personalRewardMedalVOs = [],
      teamRewardMedalVOs = [],
    } = (rewardVO||{}).rewardMedalListVO || {};
    return (
      <div className={style['tweet-left']}>
      {
        [...personalRewardMedalVOs||[],...teamRewardMedalVOs||[]].map((v, i) => {
          return <KudoItem item={v} key={i} />
        })
      }
      </div>
    )
  }
  renderComments() {
    const { commentData } = this.props.newsFeed
    const comment = commentData[this.props.feedId]
    if (util.isNull(comment)) return null
    const { comments, amount } = comment
    if (util.isNull(comments)) return null

    const fetchBtn = {
      disabled: this.state.loading || this.state.complete,
      label: this.state.loading? '加载中...': (this.state.complete && !this.state.NULL)? '没有更多评论了...': this.state.NULL? '还没有数据哦~~': '点击加载更多'
    }
    return (
      <div>
        <ul className={cx(style.comments)}>
          {
            comments.map((v, i) => (
              <li 
                style={{
                  'animationDuration': '350ms',
                  'animationDelay': `${(i%this.pageSize+1)*20}ms`
                }}
                className="animated fadeIn"
                key={i}
              >
                <Link
                  target="_blank"
                  srcIcon="avatar"
                  src={util.user(v.commentUser).avatarUrl}
                  to={v.commentUser? `#/okr/objective-targetAll?userId=${v.commentUser.userId}`: null}
                  width="30"
                />
                <div>
                  <p>
                    <Link 
                      target="_blank"
                      to={v.commentUser? `#/okr/objective-targetAll?userId=${v.commentUser.userId}`: null}
                      label={util.user(v.commentUser).fullName+':'}
                    />
                    {
                      this.decodeContent(v.content, v.atUsers)
                    }
                  </p>
                  <p>
                    <span className={style['created-time']}>{ moment(v.createdTime).fromNow() }</span>
                    <span className={style['comment-actions']}>
                      {
                        v.isDeletable?
                          <Link 
                            onClick={() => this.requestDeleteComment(v)}
                            className={style.delete} 
                            label="删除"/>
                        : null
                      }
                      <Link 
                        className={style.reply} 
                        label="回复" 
                        onMouseDown={(e) => {e.preventDefault()}}
                        onClick={() => this.handleReply(v)}/>
                    </span>
                  </p>
                </div>
              </li>
            ))
          }
        </ul>
        {
          // 没有评论或一页不到的不显示加载更多按钮
          (this.state.empty || (this.state.complete && amount <= this.pageSize))? null
          : (
            <Button 
              {...fetchBtn}
              onClick={() => this.fetchComments()}
              className={style['fetch-more-comment']}
              white/>
          )
        }
      </div>
    )
  }

  renderAccount = ({ userId, avatarUrl, fullName }, createdTime,rewardVO) => (
    <ImgTxt
      target="_blank"
      src={avatarUrl}
      name={fullName}
      title={moment(createdTime).fromNow()}
      to={userId? `#/okr/objective-targetAll?userId=${userId}`: ''}
      rewardVO={rewardVO}
    />
  )

  renderTweet() {
    if (util.isNull(this.props.content)) return null;
    
    return (
      <div 
        className={cx(style.tweet, 'animated fadeIn')}
      >
        <div className={style['tweet-right']}>
        {
          this.props.content.split(/\n/g).map((str, i) => (
            <div key={i}>{ this.decodeContent(str, this.props.atUsers, i) }</div>
          ))
        }
        </div>
      </div>
    )
  }

  renderUps() {
    const { upData } = this.props.newsFeed
    const ups = upData[this.props.feedId]
    if (util.isNull(ups)) return null
    return (
      <ul className={style['feed-ups']}>
        {
          ups.map((v, i) => {
            /*
            const Item = Tip(
              <li>
                <ImgTxt
                  className={style['feed-up-user']}
                  width="25"
                  small
                  src={v.thumbupUser.avatarUrl}
                  to={`#/user/${v.thumbupUser.userId}`}
                />
              </li>
            )
            return (
              <Item 
                key={i}
                root={`.${styleContent.root}`}
                top
                tip={v.thumbupUser.fullName}
              />
            )
            */
            const user = util.user(v.thumbupUser)
            return (
              <li
                key={i}
              >
                <Link
                  target="_blank"
                  title={user.fullName}
                  className={style['feed-up-user']}
                  width="25"
                  srcIcon="avatar"
                  src={user.avatarUrl}
                  to={user.userId? `#/okr/objective-targetAll?userId=${user.userId}`: ''}
                />
              </li>
            )
          })
        }
      </ul>
    )
  }
  toggleTweetInput = (flag) => {
    this.setState({
      toggleTweetInput: flag
    });
  }
  handleCommentClick = () => {
    this.setState({
      toggleTweetInput: !this.state.toggleTweetInput
    });
  }
  renderContent() {
    if (!this.state.render) return null;
    const { commentData } = this.props.newsFeed
    const comment = commentData[this.props.feedId]
    const { comments, amount=0 } = comment||{};
    return (
      <div>
        <div className={style['tweet-content']}>
          {
            this.renderTweet()
          }
          {
            this.renderImages()
          }
          {
            //this.renderUps()
          }
          <div className={style['feed-bar']} onMouseDown={(e) => {e.preventDefault()}}>
            <TipIconButton
              className={cx({
                [style['feed-up']]: true,
                [style['feed-arrow']]: this.state.toggleTweetInput,
              })}
              onClick={this.handleCommentClick}
              icon="chat"
              size="16"
            />
            <span className={cx({
              [style['feed-active']]: this.state.toggleTweetInput,
            })} style={{paddingRight: '10px'}}>{amount == 0? "": `${amount}`}</span>
            <TipIconButton 
              onClick={::this.handleFeedUp}
              icon={this.props.isLikable? "zan-unclicked": "zan-clicked"}
              className={cx({
                [style['feed-up']]: true,
                [style['feed-line']]: true,
              })}
              size="22"
            />
            <span>{this.props.likeNumber == 0? "": `${this.props.likeNumber}`}</span>
          </div>
        </div>
        <div className={style['comment-area']} style={{height: this.state.toggleTweetInput ? 'auto' : '0px', overflow: this.state.toggleTweetInput ? 'visible' :'hidden'}}>
          {
            this.renderComments()
          }
          <div style={{margin: '10px 0'}}>
            <TweetInput
              multi
              ref="input"
              className={style['comment-input']}
              onSubmit={::this.handleSubmit}
              atList={this.props.atList}
              fetchAtList={keyword => this.props.fetchAtList({ keyword, type: 4 })}
              label="写评论.." 
            />
          </div>
        </div>
      </div>
    )
  }

  render() {
    const feedUser = util.user(this.props.feedUser)
    return (
      <li className={cx({
        [this.props.className]: this.props.className
      })}>
        <div>
          { 
            this.renderAccount(
              feedUser,
              this.props.createdTime,
              this.props.rewardVO,
            ) 
          }
          {
            this.renderContent()
          }
          {
            this.props.isDeletable?
            <Link 
              onClick={::this.openMenu}
              icon="arrow" 
              className={style['delete-feed']}/>
            : null
          }
          {
            this.renderMenu()
          }
          {
            this.renderKudo()
          }
        </div>
        <Modal
          close
          active={this.state.deleteFeedComment}
          onRequestClose={() => util.dialog.call(this, 'deleteFeedComment')}
          actions={[
            'cancel',
            ::this.handleDeleteComment
          ]}
          title="删除评论"
        >
					<div>
            <p>确定删除这条评论吗?</p>
					</div>
        </Modal>
        <Modal
          active={this.state.deleteFeed}
          onRequestClose={() => util.dialog.call(this, 'deleteFeed')}
          actions={[
            'cancel',
           ::this.handleDeleteFeed
          ]}
          title="删除动态"
        >
					<div>
            <p>确定删除这条动态吗?</p>
					</div>
        </Modal>
      </li>
    )
  }
}
